﻿using CoachingOrganizer.ClientInfrastructure.ServicesEntities.LocalStorage;
using CoachingOrganizer.Logic.Common;
using CoachingOrganizer.Logic.Models.Common;
using CoachingOrganizer.Toolkit.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoachingOrganizer.Logic.Logic.Common
{
    internal class PeriodLogic
    {
        private readonly PeriodModel _model;
        private readonly LogicExtender _logicExtender;
        private readonly InteractionLogic _upperLogic;
        private readonly IPeriodInfo _localData;
        private readonly List<GoalLogic> _goals = new List<GoalLogic>();

        public PeriodModel Model
        {
            get { return _model; }
        }

        public IPeriodInfo LocalData
        {
            get { return _localData; }
        }

        public PeriodLogic(PeriodModel model, LogicExtender logicExtender, InteractionLogic upperLogic, IPeriodInfo localData)
        {
            _model = model;
            _logicExtender = logicExtender;
            _upperLogic = upperLogic;
            _localData = localData;
            model.RemoveDelegate = Remove;
            model.SaveDelegate = Save;
            model.EnumerateGoalsDelegate = EnumerateGoals;
            model.AddNewGoalDelegate = AddNewGoal;
        }

        public ActionResult RemoveGoal(GoalLogic logicObject)
        {
            ActionResult outResult = logicObject.LocalData.Remove();
            if (outResult.IsValid)
            {
                _goals.Remove(logicObject);
                _model.ModifyGoalsCollection(col => col.Remove(logicObject.Model));
            }
            return outResult;
        }

        private ActionResult Remove()
        {
            return _upperLogic.RemovePeriod(this);
        }

        private ActionResult Save()
        {
            _localData.Start = _model.StartDate;
            _localData.Finish = _model.FinishDate;
            return _localData.Save();
        }

        private ActionResult<IEnumerable<GoalLogic>> EnumerateGoals()
        {
            //ActionResult loadResult = _localData.LoadGoals();
            IEnumerable<IGoalInfo> goalsInfo = _localData.GoalsInfo;
            return /*loadResult.IsValid ?*/ ActionResult<IEnumerable<GoalLogic>>.GetValidResult(goalsInfo.Select(i => CreateGoalLogic(i)));// : ActionResult<IEnumerable<GoalLogic>>.GetErrorResult(loadResult);
        }

        private ActionResult<GoalLogic> AddNewGoal(Action<IGoalInfo> initCallback)
        {
            ActionResult<IGoalInfo> addResult = _localData.AddNewGoal(initCallback);
            return addResult.IsValid ? ActionResult<GoalLogic>.GetValidResult(CreateGoalLogic(addResult.Result)) : ActionResult<GoalLogic>.GetErrorResult(addResult);
        }

        private GoalLogic CreateGoalLogic(IGoalInfo info)
        {
            GoalLogic outResult = new GoalLogic(new GoalModel
            {
                Title = info.Title,
                Description = info.Description,
                ExpectedResultVolume = info.ExpectedResultVolume
            }, _logicExtender, this, info);
            _goals.Add(outResult);
            return outResult;
        }
    }
}
